import 'dart:convert';
import 'package:flutter_getx/app/data/api/api.dart';
import 'package:flutter_getx/app/data/db/entity/message.dart';
import 'package:flutter_getx/app/service/db_service.dart';
import 'package:flutter_getx/app/service/local_storage_service.dart';
import 'package:flutter_getx/app/service/user_info_service.dart';
import 'package:flutter_getx/app/util/dio/dio_config.dart';
import 'package:get/get.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import '../data/model/chat_message.dart';

class MessageService extends GetxService {
  UserInfoService userInfoService = Get.find();
  LocalStorageService localStorageService = Get.find();
  DBService dbService = Get.find();
  Api api = new Api();

  // messageMap存放全部消息
  RxMap<int, List> messageMap = new Map<int, List>().obs;
  List chatList = [].obs;
  RxSet<int> undRead = new Set<int>().obs; //消息是否已读

  late WebSocketChannel channel;

  void connect() {
    channel = WebSocketChannel.connect(
      Uri.parse(DioConfig.webSocketUrl +
          '/chat?user=' +
          userInfoService.userInfo.value.id.toString()),
    );
    // 监听websocket
    channel.stream.listen((event) {
      Message m = Message.fromJson(json.decode(event));
      print(m.content);
      if (!userInfoService.userSet.contains(m.fromUserId) && m.fromUserId == 0 && m.messageType == 1) {
        // todo
      }
      if (m.fromUserId == 0) {
        // 系统消息
        return;
      }
      var fromUid = m.fromUserId;
      var msg = MessageEntity.fromJson(json.decode(event));
      if (msg.createAt == null) {
        msg.createAt = DateTime.now().millisecondsSinceEpoch;
      }
      // 消息写入数据库
      dbService.messageDao.insertMessage(msg);

      if (messageMap[fromUid] == null) {
        print("friendId = null");
        return;
      }

      ChatMessage? chatMessage;
      switch (m.contentType) {
        case 1:
          chatMessage = new ChatMessage(
              text: m.content!,
              contentType: ChatContentType.text,
              messageStatus: MessageStatus.not_view,
              isSender: false, fromUserId: fromUid!);
          break;
        case 2:
          chatMessage = new ChatMessage(
              text: m.url!,
              contentType: ChatContentType.image,
              messageStatus: MessageStatus.not_view,
              isSender: false, fromUserId: fromUid!);
          break;
        default:
          chatMessage = null;
      }
      if (!messageMap.containsKey(fromUid)) {
        messageMap[fromUid!] = [];
      }
      this.messageMap[fromUid]?.add(chatMessage);
      messageMap.refresh();
    }, onError: (e) {
      print(e);
    }, onDone: () {
      print("--------------close---------------");
    });
  }

  // 发送消息
  void sendMessage(int to, int createAt, String content, bool isGroup) {
    String str = json.encode(Message(
            createAt: createAt,
            content: content,
            fromUserId: int.parse(userInfoService.userInfo.value.id.toString()),
            toUserId: to,
            contentType: 1,
            messageType: isGroup ? 2 : 1)
        .toJson());

    channel.sink.add(str);
  }

  Future<void> readFromDB() async {
    var users = await dbService.userDao.findAllUsers();
    users.forEach((user) async {
      var msgList = await dbService.messageDao.findMessagesByUserId(user.id!, userInfoService.userInfo.value.id!);
      List chatList = [];
      msgList.forEach((msg) {
        chatList.add(new ChatMessage(
            text: msg!.content!,
            contentType: ChatContentType.text,
            messageStatus: MessageStatus.viewed,
            isSender: userInfoService.userInfo.value.id == msg.fromUserId, fromUserId: msg.fromUserId!));
      });
      messageMap[user.id!] = chatList;
    });

    var groups = await dbService.groupMemberDao.findGroupByUserId(userInfoService.userInfo.value.id!);
    groups.forEach((group) async {
      var msgList = await dbService.messageDao.findGroupMessagesByUserId(group.groupId!);
      List chatList = [];
      msgList.forEach((msg) {
        chatList.add(new ChatMessage(
            text: msg!.content!,
            contentType: ChatContentType.text,
            messageStatus: MessageStatus.viewed,
            isSender: userInfoService.userInfo.value.id == msg.fromUserId, fromUserId: msg.fromUserId!));
      });
      messageMap[group.groupId!] = chatList;
    });
  }

  void stop() {
    channel.sink.close();
  }

  Future<MessageService> init() async {
    return this;
  }


  Future<void> infoSync() async {
    // 获取消息
    var uid = userInfoService.userInfo.value.id;
    // 获取用户私人消息 和 所在群的全部消息
    var msgList = await api.getMessage(uid);
    var ufList = await api.getUserFriendEntity(uid);
    var userList = await api.getLinkedUsers(uid);
    var groupList = await api.getAllGroup(uid);
    var gmList = await api.getAllGroupMember(uid);

    userList.forEach((e) {
      userInfoService.avatarMap[e.id!] = e.avatar!;
      userInfoService.nicknameMap[e.id!] = e.nickname!;
      userInfoService.userSet.add(e.id!);
    });

    await dbService.messageDao.deleteAll();
    await dbService.userFriendDao.deleteAll();
    await dbService.userDao.deleteAll();
    await dbService.groupMemberDao.deleteAll();
    await dbService.groupDao.deleteAll();

    // 存储到本地数据库
    await dbService.messageDao.insertMessages(msgList);
    await dbService.userFriendDao.insertUserFriends(ufList);
    await dbService.userDao.insertUsers(userList);
    await dbService.groupDao.insertGroups(groupList);
    await dbService.groupMemberDao.insertGroupMembers(gmList);
  }
}
